#ifndef __BWLIB_UTILITY_MAX_MIN_H__
#define __BWLIB_UTILITY_MAX_MIN_H__
#include "../config.h"
#include "../type_traits/all_same.h"

namespace bwlib
{
	/* @brief: 计算 max(a, b)
	   @complexity: O(1)
	   @param: a, b
	   @return: max(a, b) */
	template<typename Type>
	inline const Type& max(const Type& a, const Type& b)
	{
		return a < b ? b : a;
	}

	/* @brief: 计算 min(a, b)
	   @complexity: O(1)
	   @param: a, b
	   @return: min(a, b) */
	template<typename Type>
	inline const Type& min(const Type& a, const Type& b)
	{
		return a > b ? b : a;
	}

#ifdef __BWLIB_CXX11
	/* @brief: 计算 max(ai), 1 <= i <= n
	   @complexity: O(n)
	   @param: x1, ..., xn, with the same type
	   @return: max(ai), 1 <= i <= n */
	template<typename T0, typename... Types>
	inline const T0& max(const T0& x1, const Types&... xn)
	{
		static_assert(
			all_same<T0, Types...>::value, 
			"Types are not the same");
		return max(x1, max(xn...));
	}

	/* @brief: 计算 min(ai), 1 <= i <= n
	   @complexity: O(n)
	   @param: x1, ..., xn, with the same type
	   @return: min(ai), 1 <= i <= n */
	template<typename T0, typename... Types>
	inline const T0& min(const T0& x1, const Types&... xn)
	{
		static_assert(
			all_same<T0, Types...>::value, 
			"Types are not the same");
		return min(x1, min(xn...));
	}
#endif
}

#endif
